/**
 * @filename:ReceiveServiceImpl Jan 14, 2025
 * @project Wonder Vue Admin Api  1.1.0
 * Copyright(c) 2022 Wonder Co. Ltd. 
 * All right reserved. 
 */
package com.wonder.app.service.impl;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.admin.service.IVtuzxKingdeeService;
import com.wonder.admin.service.impl.VtuzxKingdeeServiceImpl;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.*;
import com.wonder.app.service.*;
import com.wonder.app.domain.Material;
import com.wonder.app.domain.Receive;
import com.wonder.app.domain.Receivedetail;
import com.wonder.app.mapper.MaterialDao;
import com.wonder.app.mapper.ReceiveDao;
import com.wonder.app.mapper.ReceiveWeightDao;
import com.wonder.app.mapper.ReceivedetailDao;
import com.wonder.app.service.MaterialService;
import com.wonder.app.service.ReceiveService;
import com.wonder.app.request.ReceiveRequest;
import com.wonder.app.service.ReceiveWeightService;
import com.wonder.app.service.ReceivedetailService;
import com.wonder.bean.kingdee.VtuzxKingdeeCloudClient;
import com.wonder.bean.kingdee.xqc.VtuzxArrayList;
import com.wonder.common.utils.StringUtils;


import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.List;

import java.time.LocalDate;
import java.util.*;

import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.web3j.abi.datatypes.primitive.Int;

/**   
 * @Description:TODO(收料通知单服务实现)
 *
 * @version: 1.1.0
 * @author: Wonder
 * 
 */
@Service
public class ReceiveServiceImpl  extends ServiceImpl<ReceiveDao, Receive> implements ReceiveService {
	/** 日志 */
	private static final Logger _logger = LoggerFactory.getLogger(ReceiveServiceImpl.class);
	/**
	 * 验证收料通知单信息
	 *
	 * @param receive
	 * @param type
	 * @return String
	 */
	@Autowired
	private ReceiveService receiveService;
	@Autowired
	private ReceiveDao receiveDao;
	@Autowired
	private ReceivedetailService receivedetailService;
	@Autowired
	private ReceivedetailDao receivedetailDao;
	@Autowired
	private ReceiveWeightService receiveWeightService;
	@Autowired
	private ReceiveWeightDao receiveWeightDao;
	@Autowired
	private MaterialService materialService;
	@Autowired
	private MaterialDao materialDao;
	@Autowired
	private AbnormalService abnormalService;
	@Autowired
	private AbnormalDao abnormalDao;
	@Autowired
	private InspectService inspectService;


	@Autowired
	private YzjService yzjService;

	@Autowired
	private IVtuzxKingdeeService vtuzxKingdeeService;

	@Autowired
	private InspectDetailService inspectDetailService;

	@Autowired
	private InspectDao inspectDao;
	@Autowired
	private PurInspectDetailService purInspectDetailService;
	@Autowired
	private PurInspectDetailDao purInspectDetailDao;
	@Autowired
	private IVtuzxKingdeeService kingdeeService;

	@Autowired
	private PurInDetailService purInDetailService;

	@Autowired
	private PurInService purInService;

	@Autowired
	private PurInDao purInDao;

	@Autowired
	private PurInDetailDao purInDetailDao;

	@Autowired
	private InspectDetailDao inspectDetailDao;

	@Autowired
	private SyncKingdeeOrderService syncKingdeeOrderService;
	@Override
	public String validate(Receive receive, String type) {


		return "";
	}


	/**
	 * Description:收料通知单分页返回
	 *
	 * @param request //检索条件
	 * @param page    //分页参数
	 * @return IPage<Receive>   //分页记录
	 */
	@Override
	public IPage<Receive> selectList(ReceiveRequest request, Page<Receive> page) {
		LambdaQueryWrapper<Receive> lambdaQueryWrapper = new LambdaQueryWrapper<>();

		if (null != request.getId()) {
			lambdaQueryWrapper.eq(Receive::getId, request.getId());
		}
		if (StringUtils.hasText(request.getBillNo())) {
			lambdaQueryWrapper.like(Receive::getBillNo, request.getBillNo());
		}
		if (StringUtils.hasText(request.getPurDept())) {
			lambdaQueryWrapper.like(Receive::getPurDept, request.getPurDept());
		}
		if (StringUtils.hasText(request.getPurChaser())) {
			lambdaQueryWrapper.like(Receive::getPurChaser, request.getPurChaser());
		}
		if (request.getDATE() != null) {
			Date[] fCREATEDATE = request.getDATE();
			if (fCREATEDATE.length > 0) {
				// 设置开始时间为当天的零点
				Calendar startCalendar = Calendar.getInstance();
				startCalendar.setTime(fCREATEDATE[0]);
				startCalendar.set(Calendar.HOUR_OF_DAY, 0);
				startCalendar.set(Calendar.MINUTE, 0);
				startCalendar.set(Calendar.SECOND, 0);
				startCalendar.set(Calendar.MILLISECOND, 0);
				Date startDate = startCalendar.getTime();
				lambdaQueryWrapper.ge(Receive::getDATE, startDate);
			}
			if (fCREATEDATE.length == 2) {
				// 设置结束时间为当天的24点
				Calendar endCalendar = Calendar.getInstance();
				endCalendar.setTime(fCREATEDATE[1]);
				endCalendar.set(Calendar.HOUR_OF_DAY, 23);
				endCalendar.set(Calendar.MINUTE, 59);
				endCalendar.set(Calendar.SECOND, 59);
				endCalendar.set(Calendar.MILLISECOND, 999);
				Date endDate = endCalendar.getTime();
				lambdaQueryWrapper.le(Receive::getDATE, endDate);
			}
		}

		//默认为否
		if(!VtuzxUtil.isEmpty(request.getIsChecked())){
			lambdaQueryWrapper.eq(Receive::getIsChecked,request.getIsChecked());
		}
		//默认为否
		if(!VtuzxUtil.isEmpty(request.getIsWeight())){
			lambdaQueryWrapper.eq(Receive::getIsWeight,request.getIsWeight());
		}
		// ✅ 详情表字段：StockName（仓库名称） → 使用子查询
		if (null != request.getStockNo()) {
			String stockNo = request.getStockNo().replace("'", "''"); // 防注入
			lambdaQueryWrapper.inSql(Receive::getBillNo,
					"SELECT BillNo FROM t_pur_receive_detail WHERE StockNumber = '" + stockNo + "'");
		}

		lambdaQueryWrapper.orderByDesc(Receive::getId);
		Page<Receive> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
		return selectPage;
	}


	/**
	 * 采购称重第一次扫描
	 * @param bh
	 * @return
	 */
	@Override
	public Boolean firpurweight(String bh){
		// 根据bh查询是否有数据
		QueryWrapper<Receive> wrapper = new QueryWrapper<>();
		wrapper.eq("Fid", bh)
				.and(w -> w.ne("isFailure", 1).or().isNull("isFailure"));
		Receive receive = receiveDao.selectOne(wrapper);
		if (receive != null){
			return  true;
		}else {
			return  false;
		}
	}

	@Override
	public Map<String, Object> getReceiveListPhone(Map<String, Object> map) {
		int pageIndex = VtuzxUtil.getInt(map,"pageIndex");
		int pageSize = VtuzxUtil.getInt(map,"pageSize");
		String billNo = VtuzxUtil.getString(map,"billNo");//订单号
		List<Receive> dataList = receiveDao.getReceiveList(pageSize,pageIndex * pageSize,billNo);
		Map<String,Object> data = new HashMap<>();
		data.put("dataList",dataList);
		return data;
	}

	@Override
	public Boolean purweight(Map<String, Object> data) {
		return null;
	}

	/**
	 * 地磅接口第二次称重
	 * @param bh
	 * @param sl
	 * @return
	 */
	@Override
	public VtuzxMap purweight(String bh, String sl) throws Exception{
		//解析Map集合
		String Fid = bh;//标识
		String BillNo = "";
		String materialNo = "";
		double ydqty = 0;
		double slqty = 0;
		double ycclsl = 0;
		// 根据bh查询是否有数据
		QueryWrapper<Receive> wrapper = new QueryWrapper<>();
		wrapper.eq("Fid", bh);
		Receive receive = receiveDao.selectOne(wrapper);
		if (receive != null) {
			BillNo = receive.getBillNo();
		}
		QueryWrapper<Receivedetail> receivedetailQueryWrapper = new QueryWrapper<>();
		receivedetailQueryWrapper.eq("BillNo",BillNo);
		Receivedetail receivedetail =receivedetailDao.selectOne(receivedetailQueryWrapper);
		if (receivedetail != null) {
			materialNo = receivedetail.getMaterialNumber();
			ydqty = receivedetail.getDeliveQty();
			slqty = receivedetail.getWeightResultQty();
			ycclsl = receivedetail.getAbnormalQty();
		}
		Double weight = Double.parseDouble(sl.toString());//重量//查询物料换算关系计算吨数转换后数量
		double conversion = 1;
		VtuzxKingdeeCloudClient client = vtuzxKingdeeService.loginKingdee();
		//根据物料件号查询单位编码
		List<VtuzxMap> prdInQuery = vtuzxKingdeeService.query(client, "BD_MATERIAL", new VtuzxArrayList<>(
						"F_PSUH_Decimal_re5"
				),
				String.format("fnumber = '%s'", materialNo),null , 0, 0);
		if (!VtuzxUtil.isEmpty(prdInQuery)) {
			conversion = VtuzxUtil.getDouble(prdInQuery.get(0),"F_PSUH_Decimal_re5");
			if (conversion == 0){
				conversion = 1;
			}

		} else {
			throw new RuntimeException(String.format("金蝶不存在物料%s",materialNo));
		}

		//计算转换后数量 + 已收料数量
		Double conweight = weight * conversion + slqty;
		Double bcweight = weight * conversion;
		Double reQty = ydqty -slqty;//剩余收料数量
		//异常处理数据
		VtuzxMap abmap = new VtuzxMap();
		abmap.append("ReceiveBillNo",BillNo)
				.append("SourceQty",ydqty)
				.append("zqty",conweight)
				.append("AbnormalQty",bcweight)
				.append("reQty",reQty)
				.append("PurBillNo",receive.getPurOrderNo())
				.append("MaterialNumber",receivedetail.getMaterialNumber())
				.append("MaterialName",receivedetail.getMaterialName())
				.append("UnitNumber",receivedetail.getUnitNumber())
				.append("UnitName",receivedetail.getUnitName())
				.append("supplierNo",receive.getSupplierNo())
				.append("supplierName",receive.getSupplierName())
				.append("purChaser",receive.getPurChaser())
				.append("recevieDetialid",receivedetail.getId())
				.append("specification",receivedetail.getSpecification());
		VtuzxMap resmap = new VtuzxMap();
		//超重走异常处理，未超重走来料检验本次数量大于剩余数量
		if (reQty < bcweight){
			receivedetail.setAbnormalQty(bcweight-reQty + ycclsl);
			//保存异常处理单
			resmap = SavePurAbnormal(abmap);
			//补齐剩余收料数量
			if (conweight > ydqty) {
				receivedetail.setWeightResultQty(ydqty);
			}else {
				receivedetail.setWeightResultQty(conweight);
			}
			receive.setIsFailure(1);//超重第一次后失效1，0或空都不为失效
			String BillNolljy = "";
			//修改收料通知单数量
			boolean res = receivedetailService.updateById(receivedetail);
			boolean reshead = receiveService.updateById(receive);//修改单据头失效
			if (res == true && reQty >= 0) {
				//修改金蝶
				//生成来料检验单
				resmap =  SaveInspect(abmap,bh,sl,resmap.getString("BillNo"));
			}
		}else {
			if (conweight > ydqty) {
				receivedetail.setWeightResultQty(ydqty);
			}else {
				receivedetail.setWeightResultQty(conweight);
			}
			String BillNolljy = "";
			//修改收料通知单数量
			boolean res = receivedetailService.updateById(receivedetail);
			if (res == true) {
				//修改金蝶

				//生成来料检验单
				resmap =  SaveInspect(abmap,bh,sl,"");
			}
		}
		return resmap;
	}

	/**
	 * 保存异常处理单
	 * @return
	 */
	private VtuzxMap SavePurAbnormal(VtuzxMap abmap) throws Exception {
		Abnormal abnormal= new Abnormal();
		String BillNo = IXqcConst.createBillNo(BillType.YCCL);
		abnormal.setBillNo(BillNo);
		//本次减剩余小于等于0不超重，本次数量来料检验
		if (abmap.getDouble("AbnormalQty") - abmap.getDouble("reQty") <= 0) {
			abnormal.setAbnormalQty(abmap.getDouble("AbnormalQty"));//本次来料数量
		}else {//补齐剩余数量
			abnormal.setAbnormalQty(abmap.getDouble("AbnormalQty")-abmap.getDouble("reQty"));//剩余数量
		}
		abnormal.setPurBillNo(abmap.getString("PurBillNo"));
		abnormal.setReceiveBillNo(abmap.getString("ReceiveBillNo"));
		abnormal.setMaterialName(abmap.getString("MaterialName"));
		abnormal.setMaterialNumber(abmap.getString("MaterialNumber"));
		abnormal.setSourceQty(abmap.getDouble("SourceQty"));
		abnormal.setUnitName(abmap.getString("UnitName"));
		abnormal.setUnitNumber(abmap.getString("UnitNumber"));
		abnormal.setBcWeight(abmap.getDouble("AbnormalQty"));
		abnormal.setDate(new Date());
		boolean res = abnormalService.save(abnormal);
		List<Abnormal> abnormalList = new ArrayList<>();
		abnormalList.add(abnormal);
		VtuzxMap result = new VtuzxMap();
		if (res)
		{
			try {
				syncKingdeeOrderService.syncAbnormal(abnormal);
			} catch (Exception e) {
				_logger.info(e.getMessage());
			}
			result.append("result",res)
					.append("BillNo",BillNo);
		}
		//超重给采购发通知
		yzjService.sendMsgToPur(BillNo);
		return result;

	}


	/**
	 * 生成来料检验单
	 * @param abmap
	 * @return
	 */
	private VtuzxMap SaveInspect(VtuzxMap abmap,String bh,String sl,String abBillno){
		Inspect inspect = new Inspect();
		PurInspectDetail purInspectDetail = new PurInspectDetail();
		PurInspectDetail abInspectDetail = new PurInspectDetail();
		String BillNo = IXqcConst.createBillNo(BillType.LLJY);

		inspect.setBillNo(BillNo);
		inspect.setReceiveBillNo(abmap.getString("ReceiveBillNo"));
		inspect.setSupplierNo(abmap.getString("supplierNo"));
		inspect.setSupplierName(abmap.getString("supplierName"));
		inspect.setPurChaser(abmap.getString("purChaser"));
		inspect.setStatus("save");
		inspect.setCreateUserName("称重");
		inspect.setCreateTime(new Date());
		//单据体
		List<PurInspectDetail> purInspectDetailList = new ArrayList<>();
		//正常收料部分
		purInspectDetail.setBillNo(BillNo);
		purInspectDetail.setMaterialNo(abmap.getString("MaterialNumber"));
		purInspectDetail.setMaterialName(abmap.getString("MaterialName"));
		purInspectDetail.setReveiveId(abmap.getLong("recevieDetialid"));
		purInspectDetail.setSpecification(abmap.getString("specification"));
		purInspectDetail.setUnitNo(abmap.getString("UnitNumber"));
		purInspectDetail.setUnitName(abmap.getString("UnitName"));
		//本次减剩余小于等于0不超重，本次数量来料检验
		if (abmap.getDouble("AbnormalQty") - abmap.getDouble("reQty") <= 0) {
			purInspectDetail.setInspectQty(abmap.getDouble("AbnormalQty"));//本次来料数量
			purInspectDetail.setQualifiedQty(abmap.getDouble("AbnormalQty"));//合格数量
		}else {//补齐剩余数量
			purInspectDetail.setInspectQty(abmap.getDouble("reQty"));//剩余数量
			purInspectDetail.setQualifiedQty(abmap.getDouble("reQty"));//合格数量
		}
		purInspectDetail.setUnqualifiedQty(0.0);
		purInspectDetail.setResult("未检");
		purInspectDetail.setReceiveBillNo(abmap.getString("ReceiveBillNo"));//单据体收料童子单号
		long ab = 1;
		purInspectDetail.setIsAbnomal(ab);//否
		if(abmap.getDouble("reQty") != 0){
			purInspectDetailList.add(purInspectDetail);
		}
		//异常收料部分
		if(abmap.getDouble("reQty") < abmap.getDouble("AbnormalQty")){
			abInspectDetail.setBillNo(BillNo);
			abInspectDetail.setMaterialNo(abmap.getString("MaterialNumber"));
			abInspectDetail.setMaterialName(abmap.getString("MaterialName"));
			abInspectDetail.setSpecification(abmap.getString("specification"));
			abInspectDetail.setUnitNo(abmap.getString("UnitNumber"));
			abInspectDetail.setUnitName(abmap.getString("UnitName"));
			//本次减剩余小于等于0不超重，本次数量来料检验
			if (abmap.getDouble("AbnormalQty") - abmap.getDouble("reQty") <= 0) {
				abInspectDetail.setInspectQty(abmap.getDouble("AbnormalQty"));//本次来料数量
				abInspectDetail.setQualifiedQty(abmap.getDouble("AbnormalQty"));//本次来料数量
			}else {//补齐剩余数量
				abInspectDetail.setInspectQty(abmap.getDouble("AbnormalQty")-abmap.getDouble("reQty"));//剩余数量
				abInspectDetail.setQualifiedQty(abmap.getDouble("AbnormalQty")-abmap.getDouble("reQty"));//剩余数量
			}

			abInspectDetail.setUnqualifiedQty(0.0);
			abInspectDetail.setResult("未检");
			abInspectDetail.setReceiveBillNo("");//单据体收料童子单号
			ab = 0;
			abInspectDetail.setIsAbnomal(ab);//是
			abInspectDetail.setAbBillNo(abBillno);
			purInspectDetailList.add(abInspectDetail);
		}

		boolean reshead = inspectService.save(inspect);
		boolean resdetail = purInspectDetailService.saveBatch(purInspectDetailList);
		VtuzxMap result = new VtuzxMap();
		String msg = "action=save&bh="+bh+"&sl="+sl;
		if (reshead & resdetail)
		{
			result.append("result",reshead)
					.append("BillNo",BillNo)
					.append("bh",bh)
					.append("msg",msg);
		}
		return result;
	}
	/**
	 * receive详情
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map<String, Object> getReDetail(Long user_id,Map<String, Object> map) throws Exception{
		String billNo = map.get("billNo").toString();
		Receive receform = receiveDao.selectOne(new LambdaQueryWrapper<Receive>()
				.eq(Receive::getBillNo,billNo));
		List<Receivedetail> receList = receivedetailDao.selectList(new LambdaQueryWrapper<Receivedetail>()
				.eq(Receivedetail::getBillNo,billNo));


		Map<String,Object> data = new HashMap<>();
		String qrCode = "B" + receform.getId() +"\n" +billNo +"\n" + receform.getSupplierName() +
				"\n" + receList.get(0).getMaterialNumber() + "\n" + receList.get(0).getMaterialName()
				+ "\n" + receList.get(0).getUnitName() + "\n" + receList.get(0).getSpecification() + "\n"
				+ "2";

		//查询已经下推的来料检验单，计算下推的物料数量
		List<Inspect> inspects = inspectDao.selectList(new LambdaQueryWrapper<Inspect>()
				.eq(Inspect::getReceiveBillNo, billNo));
		List<String> inspectNoList = new ArrayList<>();
		Map<String,Object> materialMap = new HashMap<>();//key:收料详情id val:数量
		if (null != inspects && inspects.size() > 0){
			for (Inspect inspect : inspects){
				String billNo1 = inspect.getBillNo();
				if (!inspectNoList.contains(billNo1)){
					inspectNoList.add(billNo1);
				}
			}
			List<InspectDetail> inspectDetails = inspectDetailDao.selectList(new LambdaQueryWrapper<InspectDetail>()
					.in(InspectDetail::getBillNo, inspectNoList)
					.eq(InspectDetail::getIsAbnomal,true));
			for (InspectDetail detail : inspectDetails){
//				String materialNo = detail.getMaterialNo();
				Long reveiveId = detail.getReveiveId();//收料详情id
				Double inspectQty = detail.getInspectQty();
				Double materialCount = VtuzxUtil.getDouble(materialMap,reveiveId.toString());
				materialMap.put(reveiveId.toString(),materialCount + inspectQty);
			}
		}
		//添加收料通知单已经下推来料检验的数量
		for (Receivedetail receivedetail : receList){
//			String materialNo = receivedetail.getMaterialNumber();
			Long receivedetailId = receivedetail.getId();//收料详情id
			Double inspectCount = VtuzxUtil.getDouble(materialMap,receivedetailId.toString());
			receivedetail.setInspectCount(inspectCount);
			receivedetail.setWeightResultQty(receivedetail.getDeliveQty() - inspectCount);//实收数量 = 交货数量 -下推数量
			//查询物料是否启用批号
			Boolean aBoolean = materialIsFlot(user_id,receivedetailId.toString());
			receivedetail.setIsBatch(aBoolean);
		}

		data.put("data",receform);
		data.put("dataList",receList);
		data.put("qrCode",qrCode);
		return data;
	}

	@Override
	public Boolean createReceive(String userName, Map<String, Object> map) {
		String supplerNo = VtuzxUtil.getString(map,"SupplierNo");
		String SupplierName = VtuzxUtil.getString(map,"SupplierName");
		String materialNo = VtuzxUtil.getString(map,"MaterialNo");
		String materialName = VtuzxUtil.getString(map,"MaterialName");
		String unitName = VtuzxUtil.getString(map,"UnitName");
		String Lot = VtuzxUtil.getString(map,"Lot");
		String specification = VtuzxUtil.getString(map,"Specification");
		Double deliveQty = VtuzxUtil.getDouble(map,"DeliveQty");
		boolean isWeight = VtuzxUtil.getBoolean(map,"IsWeight");
		String billNo = IXqcConst.createBillNo(BillType.SLTZ);
		Receive receive = new Receive();
		Receivedetail receivedetail = new Receivedetail();
		receive.setBillNo(billNo);
		receive.setDATE(new DateTime());
		receive.setIsWeight(isWeight);
		receive.setSupplierName(SupplierName);
		receive.setSupplierNo(supplerNo);

		receivedetail.setBillNo(billNo);
		receivedetail.setMaterialName(materialName);
		receivedetail.setMaterialNumber(materialNo);
		receivedetail.setSpecification(specification);
		receivedetail.setUnitName("公斤");
		receivedetail.setDeliveQty(deliveQty);
		receivedetail.setLot(Lot);

		boolean res = receiveService.save(receive);
		boolean detailRes = receivedetailService.save(receivedetail);

		return res && detailRes;
	}

	@Override
	public boolean audit(JSONObject map) throws Exception {
		_logger.info("审核收料通知单"+ map.toString());
		JSONArray erceives = map.getJSONArray("ReceiveList");
		JSONObject receiveObj = (JSONObject) erceives.get(0);
		JSONArray head = receiveObj.getJSONArray("model");//单据头数据
		JSONArray detailList = receiveObj.getJSONArray("detail");//单据体数据、
		List<Receive> receiveList = new ArrayList<>();
		List<Receivedetail> receivedetailList = new ArrayList<>();
		List<Long> fidList = new ArrayList<>();//单据头需要删除的fid集合
		List<Long> entryIdList = new ArrayList<>();//单据体需要删除的entryid集合
		for (Object obj : head) {
			JSONObject jsonObject = (JSONObject) obj;
			//将json直接转成实体类
			Receive receive = jsonObject.toBean(Receive.class);
			receive.setIsChecked(false);
			Long fid = receive.getFID();
			if (!fidList.contains(fid)){
				fidList.add(fid);
			}
			//给仓管部发送通知
			try {
				Map<String,Object> data = new HashMap<>();
				data.put("billNo",receive.getBillNo());
				yzjService.sendMsgToWare(data,BillType.SLTZ.label());
			} catch (Exception e){

			}
			receiveList.add(receive);
		}
		//单据体数据
		for (Object obj : detailList) {
			JSONObject jsonObject = (JSONObject) obj;
			//将json直接转成实体类
			Receivedetail receivedetail = jsonObject.toBean(Receivedetail.class);
			receivedetail.setIsChecked(false);
			receivedetail.setIsClose(false);
			//校验批号是否是空格
			String lot = receivedetail.getLot();
			boolean isSpaces = lot.matches("\\s*");
			if(isSpaces){
				receivedetail.setLot("");
			}
			String materialNumber = receivedetail.getMaterialNumber();
			//添加物料辅助单位字段
			Material material = materialDao.selectOne(new LambdaQueryWrapper<Material>()
					.eq(Material::getMaterialNumber, materialNumber));
			if (null != material){
				receivedetail.setFAuxUnitName(material.getFAuxUnitName());
				receivedetail.setFAuxUnitNo(material.getFAuxUnitNo());
			}
			Long entryId = receivedetail.getFEntryId();
			if (!entryIdList.contains(entryId)){
				entryIdList.add(entryId);
			}
			receivedetailList.add(receivedetail);
		}


		//查询有没有需要删除的单据
		List<Receive> redelete =  receiveDao.selectList(new LambdaQueryWrapper<Receive>()
				.in(Receive::getFID,fidList));
		if (null != redelete || redelete.size() > 0){
			receiveDao.delete(new LambdaQueryWrapper<Receive>()
					.in(Receive::getFID,fidList));

		}
		List<Receivedetail> receivedetails =  receivedetailDao.selectList(new LambdaQueryWrapper<Receivedetail>()
				.in(Receivedetail::getFEntryId,entryIdList));
		if (null != receivedetails || receivedetails.size() > 0){
			receivedetailDao.delete(new LambdaQueryWrapper<Receivedetail>()
					.in(com.wonder.app.domain.Receivedetail::getFEntryId,entryIdList));

		}
		//向数据库添加数据
		boolean resHead = receiveService.saveOrUpdateBatch(receiveList);
		boolean res = receivedetailService.saveOrUpdateBatch(receivedetailList);
		return res && resHead;
	}

	@Override
	public Map<String, Object> getReceiveDetail(Long user_id,Map<String, Object> map) throws Exception {
		String billNo = map.get("billNo").toString();
		Receive receform = receiveDao.selectOne(new LambdaQueryWrapper<Receive>()
				.eq(Receive::getBillNo,billNo)
				.eq(Receive::getIsChecked,false));
		if(null == receform){
			throw new RuntimeException("单号错误请重试");
		}
		List<Receivedetail> receList = receivedetailDao.selectList(new LambdaQueryWrapper<Receivedetail>()
				.eq(Receivedetail::getBillNo,billNo)
				.eq(Receivedetail::getIsClose,false));
		//查询已经下推的来料检验单，计算下推的物料数量
		List<Inspect> inspects = inspectDao.selectList(new LambdaQueryWrapper<Inspect>()
				.eq(Inspect::getReceiveBillNo, billNo));
		List<String> inspectNoList = new ArrayList<>();
		Map<String,Object> materialMap = new HashMap<>();
		if (null != inspects && inspects.size() > 0){
			for (Inspect inspect : inspects){
				String billNo1 = inspect.getBillNo();
				if (!inspectNoList.contains(billNo1)){
					inspectNoList.add(billNo1);
				}
			}
			List<InspectDetail> inspectDetails = inspectDetailDao.selectList(new LambdaQueryWrapper<InspectDetail>()
					.in(InspectDetail::getBillNo, inspectNoList));
			for (InspectDetail detail : inspectDetails){
				String materialNo = detail.getMaterialNo();
				Double inspectQty = detail.getInspectQty();
				Double materialCount = VtuzxUtil.getDouble(materialMap,materialNo);
				materialMap.put(materialNo,materialCount + inspectQty);
			}
		}
		//添加收料通知单已经下推来料检验的数量
		for (Receivedetail receivedetail : receList){
			String materialNo = receivedetail.getMaterialNumber();
			Double inspectCount = VtuzxUtil.getDouble(materialMap,materialNo);
			receivedetail.setInspectCount(inspectCount);
			receivedetail.setWeightResultQty(receivedetail.getDeliveQty() - inspectCount);//实收数量 = 交货数量 -下推数量
			//查询物料是否启用批号
			Boolean aBoolean = materialIsFlot(user_id,materialNo);
			receivedetail.setIsBatch(aBoolean);
		}
		Map<String,Object> data = new HashMap<>();
		data.put("data",receform);
		data.put("dataList",receList);
		return data;
	}

	/**
	 * 判断物料是否启用批号
	 * @param materialNo
	 * @return
	 */
	private Boolean materialIsFlot(Long user_id,String materialNo) throws Exception{
		VtuzxKingdeeCloudClient client = null;
		try {
			client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
		}catch (Exception e){

		}
		Boolean FIsBatchManage = false;
		//查询物料是够启用批号
		List<VtuzxMap> materialQuery = vtuzxKingdeeService.query(client, "BD_MATERIAL", new VtuzxArrayList<>(
						"FIsBatchManage"//是否启用批号
				),
				String.format("FNumber = '%s'", materialNo), null, 0, 1);
		if (!VtuzxUtil.isEmpty(materialQuery)) {
			FIsBatchManage = VtuzxUtil.getBoolean(materialQuery.get(0),"FIsBatchManage");
		}
		return FIsBatchManage;
	}

	/**
	 * 金蝶反审收料通知单，反审的时候删除收料通知单和下游的所有单据
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public boolean unAudit(JSONObject map) throws Exception {
		JSONArray ReceiveList = map.getJSONArray("ReceiveList");
		List<String> billNoList = ReceiveList.toList(String.class);
		_logger.info("反审核收料通知单"+ map.toString());

		List<String> inspectNoList = new ArrayList<>();//来料检验需要删除的单据
		List<String> purInNoList = new ArrayList<>();//采购入库需要删除的单据
		//先查询下游单据有没有来料检验单和采购入库单
		List<Inspect> inspects = inspectDao.selectList(new LambdaQueryWrapper<Inspect>()
				.in(Inspect::getReceiveBillNo, billNoList));
		if(inspects.size() > 0){
			for (Inspect inspect : inspects){
				String inspectNo = inspect.getBillNo();
				if (!inspectNoList.contains(inspectNo)){
					inspectNoList.add(inspectNo);
				}
			}
			boolean remove = inspectService.remove(new LambdaQueryWrapper<Inspect>()
					.in(Inspect::getBillNo, inspectNoList));
			boolean detailRes =inspectDetailService.remove(new LambdaQueryWrapper<InspectDetail>()
					.in(InspectDetail::getBillNo, inspectNoList));
		}
		//查询采购入库单
		List<PurIn> purIns = purInDao.selectList(new LambdaQueryWrapper<PurIn>()
				.in(PurIn::getReceiveBillNo,billNoList));
		if (purIns.size() > 0){
			for (PurIn purIn : purIns){
				String purInBillNo = purIn.getBillNo();
				if (!purInNoList.contains(purInBillNo)){
					purInNoList.add(purInBillNo);
				}
			}
			boolean remove = purInService.remove(new LambdaQueryWrapper<PurIn>()
					.in(PurIn::getBillNo, purInNoList));
			boolean detailRes = purInDetailService.remove(new LambdaQueryWrapper<PurInDetail>()
					.in(PurInDetail::getBillNo, purInNoList));
		}
		//删除收料
		boolean remove = receiveService.remove(new LambdaQueryWrapper<Receive>()
				.in(Receive::getBillNo, billNoList));
		boolean detailRes = receivedetailService.remove(new LambdaQueryWrapper<Receivedetail>()
				.in(Receivedetail::getBillNo, billNoList));
		return remove && detailRes;
	}

	@Override
	public boolean receiveClose(JSONObject map) throws Exception {
		_logger.info("收料通知行关闭:"+map.toString());
		JSONArray rceives = map.getJSONArray("ReceivelList");
		JSONObject receiveObj = (JSONObject) rceives.get(0);
		String fentryId = receiveObj.getStr("entryid");//entryid
		String receiveBillNo = receiveObj.getStr("receive");//收料单号
		Receivedetail receivedetail = receivedetailDao.selectOne(new LambdaQueryWrapper<Receivedetail>()
				.eq(Receivedetail::getBillNo, receiveBillNo)
				.eq(Receivedetail::getFEntryId, fentryId));
		receivedetail.setIsClose(true);
		boolean res = receivedetailService.saveOrUpdate(receivedetail);
		//收料明细都关闭的话，关闭单据头
		Long aLong = receivedetailDao.selectCount(new LambdaQueryWrapper<Receivedetail>()
				.eq(Receivedetail::getBillNo, receiveBillNo)
				.eq(Receivedetail::getIsClose, false));
		if (aLong == 0){
			Receive receive = receiveDao.selectOne(new LambdaQueryWrapper<Receive>()
					.eq(Receive::getBillNo, receiveBillNo));
			receive.setIsChecked(true);
			receiveDao.updateById(receive);
		}
		return res;
	}

	/**
	 * 查询仓库列表
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map<String, Object> getStockList(Long user_id,Map<String, Object> map) throws Exception {
		VtuzxKingdeeCloudClient client = null;
		try {
			client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
		} catch (Exception e){
			throw new RuntimeException("金蝶账号密码错误，请在中台修改自己的金蝶账号或密码");
		}
		List<Map<String,Object>> dataList = new ArrayList<>();
		//查询物料是够启用批号
		List<VtuzxMap> materialQuery = vtuzxKingdeeService.query(client, "BD_STOCK", new VtuzxArrayList<>(
						"FName",
						"FNumber"
				),
				"", null, 0, 0);
		if (!VtuzxUtil.isEmpty(materialQuery)) {
			for (VtuzxMap data : materialQuery){
				Map<String,Object> dataMap =new HashMap<>();
				String fname = VtuzxUtil.getString(data,"FName");
				String FNumber = VtuzxUtil.getString(data,"FNumber");
				dataMap.put("stockNo",FNumber);
				dataMap.put("stockName",fname);
				dataList.add(dataMap);
			}
		}
		Map<String,Object> data = new HashMap<>();
		data.put("dataList",dataList);
		return data;
	}
	/**
	 * 修改金蝶收料通知单
	 * @return
	 */
//	public boolean updatkdreceive(){
//		return null;
//	}
    
	
}